home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Software of the Month Club / Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].zip / Amiga General Interest Volume 220 (1995)(SOMC)(Disk 2 of y)[SMCxxxC30Ix].adf / Typeface / Source / gadget.c < prev    next >
C/C++ Source or Header  |  1995-09-10  |  27KB  |  998 lines

  1. /************************/
  2. /*            */
  3. /* Gadgets for Typeface */
  4. /*            */
  5. /************************/
  6.  
  7. #include "Typeface.h"
  8.  
  9. extern struct GfxBase *GfxBase;
  10.  
  11. /* For any gadget */
  12.  
  13. void Gadg_DrawBevel(struct RastPort *rp,ULONG x,ULONG y,ULONG w,ULONG h,
  14.   UBYTE pen1,UBYTE pen2)
  15. {
  16.   SetAPen(rp,pen1);
  17.   Move(rp,x+w-2,y);
  18.   Draw(rp,x,y);
  19.   Draw(rp,x,y+h-1);
  20.   Move(rp,1+x,y+h-2);
  21.   Draw(rp,1+x,1+y);
  22.  
  23.   SetAPen(rp,pen2);
  24.   Move(rp,1+x,y+h-1);
  25.   Draw(rp,x+w-1,y+h-1);
  26.   Draw(rp,x+w-1,y);
  27.   Move(rp,x+w-2,1+y);
  28.   Draw(rp,x+w-2,y+h-2);
  29. }
  30.  
  31. void Gadg_SetTag(struct TagItem *tag,ULONG id, ULONG data)
  32. {
  33.   tag->ti_Tag = id;
  34.   tag->ti_Data = data;
  35. }
  36.  
  37. /* character selection gadget */
  38.  
  39. #define CG_XOFFSET 6
  40. #define CG_YOFFSET 3
  41.  
  42. struct CharGadgData
  43. {
  44.   UWORD cg_CharWidth,cg_CharHeight;
  45.   WORD cg_FirstX,cg_FirstY;
  46.   struct TextFont *cg_TextFont;
  47.   ULONG cg_LastPressed,cg_Pos;
  48.   BOOL cg_Pressed,cg_Redraw;
  49.   UWORD cg_SizeX,cg_SizeY;
  50.   ULONG cg_ShiftPressed;
  51. };
  52.  
  53. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  54. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  55. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  56. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  57. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  58.   struct gpInput *gpi);
  59. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  60.   struct gpGoInactive *gpgi);
  61. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  62. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg);
  63. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  64.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar,BOOL lines);
  65. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  66.   struct Gadget *gadg);
  67.  
  68. Class *InitCharGadgClass(void)
  69. {
  70. Class *super, *cl = NULL;
  71.  
  72.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  73.   {
  74.     cl = MakeClass(NULL,NULL,super,sizeof(struct CharGadgData),0);
  75.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchCharGadg;
  76.   }
  77.   return cl;
  78. }
  79.  
  80. BOOL FreeCharGadgClass(Class *cl)
  81. {
  82.   return FreeClass(cl);
  83. }
  84.  
  85. ULONG GetCharGadgWidth(UWORD width,struct TextFont *font)
  86. {
  87. struct TextFont *gadget_font;
  88.  
  89.   gadget_font = font ? font : GfxBase->DefaultFont;
  90.   return (gadget_font->tf_XSize+(CG_XOFFSET*2))*width;
  91. }
  92.  
  93. ULONG GetCharGadgHeight(UWORD height,struct TextFont *font)
  94. {
  95. struct TextFont *gadget_font;
  96.  
  97.   gadget_font = font ? font : GfxBase->DefaultFont;
  98.   return (gadget_font->tf_YSize+(CG_YOFFSET*2))*height;
  99. }
  100.  
  101. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  102. {
  103. ULONG retval;
  104.  
  105.   switch (msg->MethodID)
  106.   {
  107.     case OM_NEW:
  108.       retval = CharGadg_NEW(cl,o,(struct opSet *)msg);
  109.       break;
  110.     case OM_SET:
  111.       retval = CharGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  112.       break;
  113.     case OM_GET:
  114.       retval = CharGadg_GET(cl,o,(struct opGet *)msg);
  115.       break;
  116.     case GM_RENDER:
  117.       retval = CharGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  118.       break;
  119.     case GM_GOACTIVE:
  120.       retval = CharGadg_GOACTIVE(cl,(struct Gadget *)o,
  121.     (struct gpInput *)msg);
  122.       break;
  123.     case GM_HANDLEINPUT:
  124.       retval = CharGadg_HANDLEINPUT(cl,(struct Gadget *)o,
  125.     (struct gpInput *)msg);
  126.       break;
  127.     case GM_GOINACTIVE:
  128.       retval = CharGadg_GOINACTIVE(cl,(struct Gadget *)o,
  129.     (struct gpGoInactive *)msg);
  130.       break;
  131.     default:
  132.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  133.       break;
  134.   }
  135.   return retval;
  136. }
  137.  
  138. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  139. {
  140. ULONG retval = 0;
  141. struct CharGadgData *cgd;
  142.  
  143.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  144.   if (retval)
  145.   {
  146.     cgd = INST_DATA(cl,retval);
  147.     cgd->cg_TextFont = (struct TextFont *)
  148.       GetTagData(CG_Font,(ULONG)GfxBase->DefaultFont,ops->ops_AttrList);
  149.     cgd->cg_CharWidth = cgd->cg_TextFont->tf_XSize+(CG_XOFFSET*2);
  150.     cgd->cg_CharHeight = cgd->cg_TextFont->tf_YSize+(CG_YOFFSET*2);
  151.     cgd->cg_Pressed = FALSE;
  152.     cgd->cg_Redraw = TRUE;
  153.     cgd->cg_LastPressed = ~0;
  154.     cgd->cg_SizeX = GetTagData(CG_SizeX,8,ops->ops_AttrList);
  155.     cgd->cg_SizeY = GetTagData(CG_SizeY,8,ops->ops_AttrList);
  156.   }
  157.   return retval;
  158. }
  159.  
  160. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  161. {
  162. struct RastPort *rp;
  163. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  164. struct TextFont *old_tf = NULL;
  165. UWORD i,j;
  166.  
  167.   if (cgd->cg_Redraw == FALSE) return 0;
  168.   cgd->cg_Redraw = FALSE;
  169.  
  170.   rp = gpr->gpr_RPort;
  171.   if (rp->Font != cgd->cg_TextFont)
  172.   {
  173.     old_tf = rp->Font;
  174.     SetFont(rp,cgd->cg_TextFont);
  175.   }
  176.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  177.   {
  178.     for (i = 0; i < cgd->cg_SizeY; i++)
  179.     {
  180.       for (j = 0; j < cgd->cg_SizeX; j++)
  181.     CharGadg_DrawChar(rp,gpr->gpr_GInfo,FALSE,
  182.       (j*cgd->cg_CharWidth)+gadg->LeftEdge,
  183.       (i*cgd->cg_CharHeight)+gadg->TopEdge,
  184.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  185.       ((cgd->cg_Pos+i)*cgd->cg_SizeX)+j,
  186.       gpr->gpr_Redraw == GREDRAW_REDRAW);
  187.     }
  188.   }
  189.   if (old_tf) SetFont(rp,old_tf);
  190.   return 0;
  191. }
  192.  
  193. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  194. {
  195. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  196. struct GadgetInfo *gi;
  197. WORD i,j;
  198. ULONG retval = GMR_NOREUSE;
  199.  
  200.   DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpi);
  201.   cgd->cg_FirstX = -1; cgd->cg_FirstY = -1; cgd->cg_Pressed = TRUE;
  202.   j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  203.   i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  204.   if ((i >= 0) && (i < cgd->cg_SizeY) && (j >= 0) && (j < cgd->cg_SizeX))
  205.   {
  206.     cgd->cg_FirstX = j; cgd->cg_FirstY = i;
  207.     gi = gpi->gpi_GInfo;
  208.     CharGadg_DrawCurrent(gi,cgd,gadg);
  209.     retval = GMR_MEACTIVE;
  210.   }
  211.   return retval;
  212. }
  213.  
  214. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  215. {
  216. struct GadgetInfo *gi = gpi->gpi_GInfo;
  217. struct InputEvent *ie = gpi->gpi_IEvent;
  218. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  219. ULONG retval = GMR_MEACTIVE;
  220. WORD i,j;
  221.  
  222.   if (gi->gi_Window)
  223.   {
  224.     if ((gi->gi_Window->Flags & WFLG_WINDOWACTIVE) == 0) return GMR_NOREUSE;
  225.   }
  226.   while (ie && (retval == GMR_MEACTIVE))
  227.   {
  228.     if (ie->ie_Class == IECLASS_RAWMOUSE)
  229.     {
  230.       if (ie->ie_Code != SELECTUP)
  231.       {
  232.     cgd->cg_ShiftPressed =
  233.       ie->ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT);
  234.     j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  235.     i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  236.     if ((i == cgd->cg_FirstY) && (j == cgd->cg_FirstX))
  237.     {
  238.       if (cgd->cg_Pressed == FALSE)
  239.       {
  240.         cgd->cg_Pressed = TRUE;
  241.         CharGadg_DrawCurrent(gi,cgd,gadg);
  242.       }
  243.     }
  244.     else
  245.     {
  246.       if (cgd->cg_Pressed == TRUE)
  247.       {
  248.         cgd->cg_Pressed = FALSE;
  249.         CharGadg_DrawCurrent(gi,cgd,gadg);
  250.       }
  251.     }
  252.       }
  253.       else retval = GMR_NOREUSE|GMR_VERIFY;
  254.     }
  255.     ie = ie->ie_NextEvent;
  256.   }
  257.   return retval;
  258. }
  259.  
  260. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  261.   struct gpGoInactive *gpgi)
  262. {
  263. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  264. struct GadgetInfo *gi;
  265. struct RastPort *rp;
  266. struct TextFont *old_tf = NULL;
  267. struct TagItem inactive;
  268. ULONG retval;
  269.  
  270.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpgi);
  271.   if ((cgd->cg_FirstX != -1) && (cgd->cg_FirstY != -1))
  272.   {
  273.     gi = gpgi->gpgi_GInfo;
  274.     if (cgd->cg_Pressed == TRUE)
  275.     {
  276.       if (rp = ObtainGIRPort(gi))
  277.       {
  278.     if (rp->Font != cgd->cg_TextFont)
  279.     {
  280.       old_tf = rp->Font;
  281.       SetFont(rp,cgd->cg_TextFont);
  282.     }
  283.     CharGadg_DrawChar(rp,gi,FALSE,
  284.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  285.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  286.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  287.       ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX,
  288.       TRUE);
  289.     if (old_tf) SetFont(rp,old_tf);
  290.     ReleaseGIRPort(rp);
  291.       }
  292.       cgd->cg_LastPressed =
  293.     ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX;
  294.       Gadg_SetTag(&inactive,TAG_DONE,0);
  295.       DoMethod(gadg,OM_NOTIFY,&inactive,gi,0);
  296.     }
  297.   }
  298.   return retval;
  299. }
  300.  
  301. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  302. {
  303. struct TagItem *tags, *tag;
  304. ULONG retval;
  305. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  306. struct RastPort *rp;
  307.  
  308.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)ops);
  309.   tags = ops->ops_AttrList;
  310.   if (tags)
  311.   {
  312.     if (tag = FindTagItem(CG_Pos,tags))
  313.     {
  314.       if (cgd->cg_Pos != tag->ti_Data) cgd->cg_Pos = tag->ti_Data;
  315.     }
  316.     if (tag = FindTagItem(CG_SizeY,tags))
  317.     {
  318.       if (cgd->cg_SizeY != tag->ti_Data) cgd->cg_SizeY = tag->ti_Data;
  319.     }
  320.     if (tag = FindTagItem(CG_Redraw,tags))
  321.     {
  322.       if (rp = ObtainGIRPort(ops->ops_GInfo))
  323.       {
  324.     cgd->cg_Redraw = TRUE;
  325.     DoMethod(gadg,GM_RENDER,ops->ops_GInfo,rp,
  326.       tag->ti_Data ? GREDRAW_REDRAW : GREDRAW_UPDATE);
  327.     ReleaseGIRPort(rp);
  328.       }
  329.     }
  330.     if (tag = FindTagItem(CG_Pressed,tags))
  331.       cgd->cg_LastPressed = tag->ti_Data;
  332.   }
  333.   return retval;
  334. }
  335.  
  336. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg)
  337. {
  338. struct CharGadgData *cgd = INST_DATA(cl,o);
  339. ULONG retval = TRUE;
  340.  
  341.   switch (opg->opg_AttrID)
  342.   {
  343.     case CG_Pos:
  344.       *(opg->opg_Storage) = cgd->cg_Pos;
  345.       break;
  346.     case CG_Pressed:
  347.       *(opg->opg_Storage) = cgd->cg_LastPressed;
  348.       break;
  349.     case CG_SizeY:
  350.       *(opg->opg_Storage) = cgd->cg_SizeY;
  351.       break;
  352.     case CG_ShiftDown:
  353.       *(opg->opg_Storage) = cgd->cg_ShiftPressed;
  354.       break;
  355.     default:
  356.       retval = DoSuperMethodA(cl,o,(Msg *)opg);
  357.       break;
  358.   }
  359.   return retval;
  360. }
  361.  
  362. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  363.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar, BOOL lines)
  364. {
  365. struct DrawInfo *dri = gi->gi_DrInfo;
  366. UBYTE pen1,pen2,pen3,pen4;
  367.  
  368.   if (selected)
  369.   {
  370.     pen1 = dri->dri_Pens[SHADOWPEN];
  371.     pen2 = dri->dri_Pens[SHINEPEN];
  372.     pen3 = dri->dri_Pens[FILLTEXTPEN];
  373.     pen4 = dri->dri_Pens[FILLPEN];
  374.   }
  375.   else
  376.   {
  377.     pen1 = dri->dri_Pens[SHINEPEN];
  378.     pen2 = dri->dri_Pens[SHADOWPEN];
  379.     pen3 = dri->dri_Pens[TEXTPEN];
  380.     pen4 = dri->dri_Pens[BACKGROUNDPEN];
  381.   }
  382.   SetAPen(rp,pen4);
  383.   if (lines)
  384.   {
  385.     RectFill(rp,x,y,x+w-1,y+h-1);
  386.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  387.   }
  388.   else RectFill(rp,x+2,y+1,x+w-5,y+h-3);
  389.   SetAPen(rp,pen3);
  390.   SetBPen(rp,pen4);
  391.   SetDrMd(rp,JAM2);
  392.   Move(rp,x+CG_XOFFSET,y+CG_YOFFSET+rp->Font->tf_Baseline);
  393.   Text(rp,&gchar,1);
  394. }
  395.  
  396. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  397.   struct Gadget *gadg)
  398. {
  399. struct RastPort *rp;
  400. struct TextFont *old_tf = NULL;
  401.  
  402.   if (rp = ObtainGIRPort(gi))
  403.   {
  404.     if (rp->Font != cgd->cg_TextFont)
  405.     {
  406.       old_tf = rp->Font;
  407.       SetFont(rp,cgd->cg_TextFont);
  408.     }
  409.     CharGadg_DrawChar(rp,gi,cgd->cg_Pressed,
  410.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  411.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  412.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  413.       ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX,TRUE);
  414.     if (old_tf) SetFont(rp,old_tf);
  415.     ReleaseGIRPort(rp);
  416.   }
  417. }
  418.  
  419. /* character editing gadget */
  420.  
  421. struct EditGadgData
  422. {
  423.   UWORD eg_PixelX,eg_PixelY;
  424.   struct Character *eg_Char;
  425.   UWORD eg_XOffset,eg_YOffset;
  426.   struct CharNode *eg_Node;
  427.   UWORD eg_Button, eg_PixelBorder, eg_ShowBaseline;
  428.   ULONG eg_Baseline;
  429.   BOOL *eg_ChangePtr;
  430.   WORD eg_ActiveX, eg_ActiveY;
  431. };
  432.  
  433. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  434. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  435. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg);
  436. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  437. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  438. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  439. ULONG EditGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  440.   struct gpInput *gpi);
  441. void EditGadg_TogglePixel(struct Gadget *gadg,struct gpInput *gpi,
  442.   struct EditGadgData *egd,WORD i,WORD j);
  443.  
  444. Class *InitEditGadgClass(void)
  445. {
  446. Class *super, *cl = NULL;
  447.  
  448.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  449.   {
  450.     cl = MakeClass(NULL,NULL,super,sizeof(struct EditGadgData),0);
  451.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchEditGadg;
  452.   }
  453.   return cl;
  454. }
  455.  
  456. BOOL FreeEditGadgClass(Class *cl)
  457. {
  458.   return FreeClass(cl);
  459. }
  460.  
  461. void EditGadg_GetSize(struct EditGadgData *egd,UWORD w,UWORD h,
  462.   UWORD *ew_ptr, UWORD *eh_ptr)
  463. {
  464. struct Character *chr;
  465.  
  466.   *ew_ptr = (w-(2*EG_XOFFSET))/(egd->eg_PixelX);
  467.   *eh_ptr = (h-(2*EG_YOFFSET))/(egd->eg_PixelY);
  468.   if (chr = egd->eg_Char)
  469.   {
  470.     if (*ew_ptr > chr->chr_Width) *ew_ptr = chr->chr_Width;
  471.     if (*eh_ptr > chr->chr_Height) *eh_ptr = chr->chr_Height;
  472.   }
  473. }
  474.  
  475. void EditGadg_Draw(Object *o, struct GadgetInfo *gi,ULONG draw)
  476. {
  477. struct RastPort *rp;
  478.  
  479.   if (rp = ObtainGIRPort(gi))
  480.   {
  481.     DoMethod(o,GM_RENDER,gi,rp,draw);
  482.     ReleaseGIRPort(rp);
  483.   }
  484. }
  485.  
  486. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  487. {
  488. ULONG retval;
  489.  
  490.   switch (msg->MethodID)
  491.   {
  492.     case OM_NEW:
  493.       retval = EditGadg_NEW(cl,o,(struct opSet *)msg);
  494.       break;
  495.     case OM_GET:
  496.       retval = EditGadg_GET(cl,o,(struct opGet *)msg);
  497.       break;
  498.     case OM_SET:
  499.     case OM_UPDATE:
  500.       retval = EditGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  501.       break;
  502.     case GM_RENDER:
  503.       retval = EditGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  504.       break;
  505.     case GM_GOACTIVE:
  506.       retval = EditGadg_GOACTIVE(cl,(struct Gadget *)o,
  507.     (struct gpInput *)msg);
  508.       break;
  509.     case GM_HANDLEINPUT:
  510.       retval = EditGadg_HANDLEINPUT(cl,(struct Gadget *)o,
  511.     (struct gpInput *)msg);
  512.       break;
  513.     default:
  514.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  515.       break;
  516.   }
  517.   return retval;
  518. }
  519.  
  520. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  521. {
  522. ULONG retval = 0;
  523. struct EditGadgData *egd;
  524.  
  525.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  526.   if (retval)
  527.   {
  528.     egd = INST_DATA(cl,retval);
  529.     egd->eg_PixelX = GetTagData(EG_PixelX,32,ops->ops_AttrList);
  530.     egd->eg_PixelY = GetTagData(EG_PixelY,16,ops->ops_AttrList);
  531.     egd->eg_Char = (struct Character *)
  532.       GetTagData(EG_CharStruct,0,ops->ops_AttrList);
  533.     egd->eg_XOffset = 0;
  534.     egd->eg_YOffset = 0;
  535.     egd->eg_Node = (struct CharNode *)
  536.       GetTagData(EG_CharNode,0,ops->ops_AttrList);
  537.     egd->eg_Button = 0;
  538.     egd->eg_PixelBorder = GetTagData(EG_PixelBorder,1,ops->ops_AttrList);
  539.     egd->eg_ShowBaseline = GetTagData(EG_ShowBaseline,0,ops->ops_AttrList);
  540.     egd->eg_Baseline = GetTagData(EG_Baseline,0,ops->ops_AttrList);
  541.     egd->eg_ChangePtr = (BOOL *)GetTagData(EG_ChangePtr,0,ops->ops_AttrList);
  542.   }
  543.   return retval;
  544. }
  545.  
  546. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  547. {
  548. struct RastPort *rp;
  549. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  550. struct DrawInfo *dri = gpr->gpr_GInfo->gi_DrInfo;
  551. struct Character *chr;
  552. UBYTE pen1,pen2,pen3,pen4;
  553. UWORD ew,eh,i,j,x,y,w,h,p;
  554.  
  555.   rp = gpr->gpr_RPort;
  556.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  557.   {
  558.     if ((chr = egd->eg_Char) == NULL) return 0;
  559.     pen1 = dri->dri_Pens[SHINEPEN];
  560.     pen2 = dri->dri_Pens[SHADOWPEN];
  561.     pen3 = dri->dri_Pens[BACKGROUNDPEN];
  562.     pen4 = dri->dri_Pens[FILLPEN];
  563.     SetAfPt(rp,NULL,0);
  564.     x = gadg->LeftEdge; y = gadg->TopEdge;
  565.     w = gadg->Width; h = gadg->Height;
  566.     if (gpr->gpr_Redraw == GREDRAW_REDRAW)
  567.     {
  568.       SetAPen(rp,pen3);
  569.       RectFill(rp,x,y,x+w-1,y+h-1);
  570.     }
  571.     EditGadg_GetSize(egd,w,h,&ew,&eh);
  572.     w = (ew*(egd->eg_PixelX))+(2*EG_XOFFSET);
  573.     h = (eh*(egd->eg_PixelY))+(2*EG_YOFFSET);
  574.     p = (egd->eg_PixelBorder != 0) ? 2 : 1;
  575.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  576.     if (egd->eg_PixelBorder > 0)
  577.     {
  578.       SetAPen(rp,egd->eg_PixelBorder == 2 ? pen4 : pen3);
  579.       for (j = 0; j < eh-1; j++)
  580.       {
  581.     Move(rp,x+EG_XOFFSET,((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-1);
  582.     Draw(rp,x+w-EG_XOFFSET-1,((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-1);
  583.       }
  584.       SetAPen(rp,pen3);
  585.       Move(rp,x+EG_XOFFSET,(eh*egd->eg_PixelY)+y+EG_YOFFSET-1);
  586.       Draw(rp,x+w-EG_XOFFSET-1,(eh*egd->eg_PixelY)+y+EG_YOFFSET-1);
  587.     }
  588.     if (egd->eg_PixelBorder == 2)
  589.     {
  590.       SetAPen(rp,pen4);
  591.       for (i = 0; i < ew-1; i++)
  592.       {
  593.     Move(rp,((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-1,y+EG_YOFFSET);
  594.     Draw(rp,((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-1,y+h-EG_YOFFSET-2);
  595.       }
  596.     }
  597.     if (chr->chr_Data)
  598.     {
  599.       for (i = 0; i < ew; i++)
  600.       {
  601.     for (j = 0; j < eh; j++)
  602.     {
  603.       SetAPen(rp,(*(chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+
  604.         i+egd->eg_XOffset) != 0) ? pen2 : pen3);
  605.       RectFill(rp,(i*egd->eg_PixelX)+x+EG_XOFFSET,
  606.         (j*egd->eg_PixelY)+y+EG_YOFFSET,
  607.         ((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-p,
  608.         ((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-p);
  609.     }
  610.       }
  611.     }
  612.     if (egd->eg_ShowBaseline)
  613.     {
  614.       if (egd->eg_Baseline-egd->eg_YOffset < eh)
  615.       {
  616.     SetAPen(rp,dri->dri_Pens[SHINEPEN]);
  617.     Move(rp,x+EG_XOFFSET,((egd->eg_Baseline-egd->eg_YOffset+1)*
  618.       egd->eg_PixelY)+y+EG_YOFFSET-1);
  619.     Draw(rp,x+w-EG_XOFFSET-1,((egd->eg_Baseline-egd->eg_YOffset+1)*
  620.       egd->eg_PixelY)+y+EG_YOFFSET-1);
  621.       }
  622.     }
  623.   }
  624.   return 0;
  625. }
  626.  
  627. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg)
  628. {
  629. struct EditGadgData *egd = INST_DATA(cl,o);
  630. ULONG retval = TRUE;
  631. UWORD ew,eh;
  632.  
  633.   switch (opg->opg_AttrID)
  634.   {
  635.     case EG_Width:
  636.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  637.     ((struct Gadget *)o)->Height,&ew,&eh);
  638.       *(opg->opg_Storage) = ew;
  639.       break;
  640.     case EG_Height:
  641.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  642.     ((struct Gadget *)o)->Height,&ew,&eh);
  643.       *(opg->opg_Storage) = eh;
  644.       break;
  645.     case EG_XOffset:
  646.       *(opg->opg_Storage) = egd->eg_XOffset;
  647.       break;
  648.     case EG_YOffset:
  649.       *(opg->opg_Storage) = egd->eg_YOffset;
  650.       break;
  651.     case EG_PixelX:
  652.       *(opg->opg_Storage) = egd->eg_PixelX;
  653.       break;
  654.     case EG_PixelY:
  655.       *(opg->opg_Storage) = egd->eg_PixelY;
  656.       break;
  657.     default:
  658.       retval = DoSuperMethodA(cl,o,(Msg *)opg);
  659.       break;
  660.   }
  661.   return retval;
  662. }
  663.  
  664. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  665. {
  666. struct TagItem *tags, *tag;
  667. ULONG retval,pos;
  668. UWORD ew,eh;
  669. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  670.  
  671.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg *)ops);
  672.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  673.   tags = ops->ops_AttrList;
  674.   if (tags)
  675.   {
  676.     if (tag = FindTagItem(EG_Baseline,tags))
  677.       egd->eg_Baseline = tag->ti_Data;
  678.     if (tag = FindTagItem(EG_CharNode,tags))
  679.       egd->eg_Node = (struct CharNode *)(tag->ti_Data);
  680.     if (tag = FindTagItem(EG_CharStruct,tags))
  681.       egd->eg_Char = (struct Character *)(tag->ti_Data);
  682.     if (tag = FindTagItem(EG_PixelX,tags))
  683.       egd->eg_PixelX = tag->ti_Data;
  684.     if (tag = FindTagItem(EG_PixelY,tags))
  685.       egd->eg_PixelY = tag->ti_Data;
  686.     if (tag = FindTagItem(EG_Update,tags))
  687.     {
  688.       switch (tag->ti_Data)
  689.       {
  690.     case GADG_HORIZ:
  691.       if (egd->eg_Node)
  692.       {
  693.         GetAttr(PGA_Top,egd->eg_Node->chln_HorizGadg,&pos);
  694.         if (egd->eg_XOffset != pos)
  695.         {
  696.           egd->eg_XOffset = pos;
  697.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  698.         }
  699.       }
  700.       break;
  701.     case GADG_VERT:
  702.       if (egd->eg_Node)
  703.       {
  704.         GetAttr(PGA_Top,egd->eg_Node->chln_VertGadg,&pos);
  705.         if (egd->eg_YOffset != pos)
  706.         {
  707.           egd->eg_YOffset = pos;
  708.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  709.         }
  710.       }
  711.       break;
  712.     case GADG_LEFT:
  713.       if (egd->eg_XOffset > 0)
  714.       {
  715.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  716.         {
  717.           egd->eg_XOffset--;
  718.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  719.           SetGadgetAttrs(egd->eg_Node->chln_HorizGadg,
  720.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  721.         TAG_DONE);
  722.         }
  723.       }
  724.       break;
  725.     case GADG_RIGHT:
  726.       if (egd->eg_XOffset + ew < egd->eg_Char->chr_Width)
  727.       {
  728.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  729.         {
  730.           egd->eg_XOffset++;
  731.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  732.           SetGadgetAttrs(egd->eg_Node->chln_HorizGadg,
  733.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  734.         TAG_DONE);
  735.         }
  736.       }
  737.       break;
  738.     case GADG_UP:
  739.       if (egd->eg_YOffset > 0)
  740.       {
  741.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  742.         {
  743.           egd->eg_YOffset--;
  744.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  745.           SetGadgetAttrs(egd->eg_Node->chln_VertGadg,
  746.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  747.         TAG_DONE);
  748.         }
  749.       }
  750.       break;
  751.     case GADG_DOWN:
  752.       if (egd->eg_YOffset + eh < egd->eg_Char->chr_Height)
  753.       {
  754.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  755.         {
  756.           egd->eg_YOffset++;
  757.           EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  758.           SetGadgetAttrs(egd->eg_Node->chln_VertGadg,
  759.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  760.         TAG_DONE);
  761.         }
  762.       }
  763.       break;
  764.     case GADG_NONE:
  765.       egd->eg_XOffset = 0;
  766.       egd->eg_YOffset = 0;
  767.       EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_REDRAW);
  768.       break;
  769.       }
  770.     }
  771.     if (tag = FindTagItem(EG_XOffset,tags))
  772.     {
  773.       if (egd->eg_XOffset != tag->ti_Data)
  774.       {
  775.     egd->eg_XOffset = tag->ti_Data;
  776.     EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  777.       }
  778.     }
  779.     if (tag = FindTagItem(EG_YOffset,tags))
  780.     {
  781.       if (egd->eg_YOffset != tag->ti_Data)
  782.       {
  783.     egd->eg_YOffset = tag->ti_Data;
  784.     EditGadg_Draw(gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  785.       }
  786.     }
  787.   }
  788.   return retval;
  789. }
  790.  
  791. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  792. {
  793. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  794. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  795. WORD i,j;
  796. UWORD ew,eh;
  797.  
  798.   DoSuperMethodA(cl,(Object *)gadg,(Msg *)gpi);
  799.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  800.   i = (gpi->gpi_Mouse.X - EG_XOFFSET) / egd->eg_PixelX;
  801.   j = (gpi->gpi_Mouse.Y - EG_YOFFSET) / egd->eg_PixelY;
  802.   if ((i >= 0) && (i < ew) && (j >= 0) && (j < eh))
  803.   {
  804.     EditGadg_TogglePixel(gadg,gpi,egd,i,j);
  805.     return GMR_MEACTIVE;
  806.   }
  807.   else return GMR_NOREUSE;
  808. }
  809.  
  810. ULONG EditGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  811.   struct gpInput *gpi)
  812. {
  813. struct GadgetInfo *gi = gpi->gpi_GInfo;
  814. struct InputEvent *ie = gpi->gpi_IEvent;
  815. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  816. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  817. ULONG retval = GMR_MEACTIVE;
  818. WORD i,j;
  819. UWORD ew,eh;
  820.  
  821.   if (gi->gi_Window)
  822.   {
  823.     if ((gi->gi_Window->Flags & WFLG_WINDOWACTIVE) == 0) return GMR_NOREUSE;
  824.   }
  825.   while (ie && (retval == GMR_MEACTIVE))
  826.   {
  827.     if (ie->ie_Class == IECLASS_RAWMOUSE)
  828.     {
  829.       if (ie->ie_Code != SELECTUP)
  830.       {
  831.     EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  832.     i = (gpi->gpi_Mouse.X - EG_XOFFSET) / egd->eg_PixelX;
  833.     j = (gpi->gpi_Mouse.Y - EG_YOFFSET) / egd->eg_PixelY;
  834.     if ((i >= 0) && (i < ew) && (j >= 0) && (j < eh))
  835.     {
  836.       if ((i != egd->eg_ActiveX) || (j != egd->eg_ActiveY))
  837.         EditGadg_TogglePixel(gadg,gpi,egd,i,j);
  838.     }
  839.     else retval = GMR_NOREUSE;
  840.       }
  841.       else retval = GMR_NOREUSE;
  842.     }
  843.     ie = ie->ie_NextEvent;
  844.   }
  845.   return retval;
  846. }
  847.  
  848. void EditGadg_TogglePixel(struct Gadget *gadg,struct gpInput *gpi,
  849.   struct EditGadgData *egd,WORD i,WORD j)
  850. {
  851. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  852. struct RastPort *rp;
  853. struct Character *chr;
  854. UBYTE *pixel;
  855. UBYTE pen1,pen2;
  856. UWORD px,py;
  857.  
  858.   egd->eg_ActiveX = i;
  859.   egd->eg_ActiveY = j;
  860.   if ((chr = egd->eg_Char) == NULL) return;
  861.   if (chr->chr_Data == NULL)
  862.   {
  863.     if ((chr->chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,
  864.       MEMF_CLEAR)) == NULL) return;
  865.   }
  866.   pixel =
  867.     chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+i+egd->eg_XOffset;
  868.   if (rp = ObtainGIRPort(gpi->gpi_GInfo))
  869.   {
  870.     pen1 = dri->dri_Pens[SHADOWPEN];
  871.     pen2 = dri->dri_Pens[BACKGROUNDPEN];
  872.     if (egd->eg_PixelBorder == 0)
  873.     {
  874.       px = 1;
  875.       py = 1;
  876.       if (egd->eg_ShowBaseline)
  877.     if (j+egd->eg_YOffset == egd->eg_Baseline) py++;
  878.     }
  879.     else
  880.     {
  881.       px = 2;
  882.       py = 2;
  883.     }
  884.     SetAfPt(rp,NULL,0);
  885.     *pixel = 1-(*pixel);
  886.     SetAPen(rp,*pixel == 1 ? pen1 : pen2);
  887.     RectFill(rp,(i*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET,
  888.       (j*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET,
  889.       ((i+1)*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET-px,
  890.       ((j+1)*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET-py);
  891.     ReleaseGIRPort(rp);
  892.     *(egd->eg_ChangePtr) = TRUE;
  893.   }
  894. }
  895.  
  896. /* slider gadget subclass */
  897.  
  898. struct SlideGadgData
  899. {
  900.   ULONG sg_Total,sg_Visible;
  901. };
  902.  
  903. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  904. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu);
  905. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  906. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops);
  907.  
  908. Class *InitSlideGadgClass(void)
  909. {
  910. Class *super, *cl = NULL;
  911.  
  912.   if (super = BGUI_GetClassPtr(BGUI_PROP_GADGET))
  913.   {
  914.     cl = MakeClass(NULL,NULL,super,0,0);
  915.     if (cl) cl->cl_Dispatcher.h_Entry = DispatchSlideGadg;
  916.   }
  917.   return cl;
  918. }
  919.  
  920. BOOL FreeSlideGadgClass(Class *cl)
  921. {
  922.   return FreeClass(cl);
  923. }
  924.  
  925. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  926. {
  927. ULONG retval;
  928.  
  929.   switch (msg->MethodID)
  930.   {
  931.     case OM_NEW:
  932.       retval = SlideGadg_NEW(cl,o,(struct opSet *)msg);
  933.       break;
  934.     case OM_SET:
  935.     case OM_UPDATE:
  936.       retval = SlideGadg_SET(cl,o,(struct opSet *)msg);
  937.       break;
  938.     case OM_NOTIFY:
  939.       retval = SlideGadg_NOTIFY(cl,o,(struct opUpdate *)msg);
  940.       break;
  941.     default:
  942.       retval = DoSuperMethodA(cl,o,(Msg *)msg);
  943.       break;
  944.   }
  945.   return retval;
  946. }
  947.  
  948. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  949. {
  950. ULONG retval = 0;
  951. struct SlideGadgData *sgd;
  952.  
  953.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg *)ops);
  954.   if (retval)
  955.   {
  956.     sgd = INST_DATA(cl,retval);
  957.     sgd->sg_Total = GetTagData(PGA_Total,0,ops->ops_AttrList);
  958.     sgd->sg_Visible = GetTagData(PGA_Visible,0,ops->ops_AttrList);
  959.   }
  960.   return retval;
  961. }
  962.  
  963. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops)
  964. {
  965. struct SlideGadgData *sgd = INST_DATA(cl,o);
  966. struct GadgetInfo *gi = ops->ops_GInfo;
  967. struct TagItem *tags, *tag;
  968. struct TagItem inactive;
  969. ULONG retval;
  970.  
  971.   retval = DoSuperMethodA(cl,o,(Msg *)ops);
  972.   tags = ops->ops_AttrList;
  973.   if (tags)
  974.   {
  975.     if (tag = FindTagItem(PGA_Total,tags)) sgd->sg_Total = tag->ti_Data;
  976.     if (tag = FindTagItem(PGA_Visible,tags)) sgd->sg_Visible = tag->ti_Data;
  977.     Gadg_SetTag(&inactive,TAG_DONE,0);
  978.     DoMethod((struct Gadget *)o,OM_NOTIFY,&inactive,gi,0);
  979.   }
  980.   return retval;
  981. }
  982.  
  983. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu)
  984. {
  985. struct SlideGadgData *sgd = INST_DATA(cl,o);
  986. struct TagItem tags[3];
  987. ULONG pos = 0;
  988.  
  989.   GetAttr(PGA_Top,o,&pos);
  990.   Gadg_SetTag(&tags[0],GA_ID,((struct Gadget *)o)->GadgetID);
  991.   Gadg_SetTag(&tags[1],SCRL_Right,sgd->sg_Total-sgd->sg_Visible-pos);
  992.   if (opu->opu_AttrList == NULL)
  993.     Gadg_SetTag(&tags[2],TAG_DONE,0);
  994.   else
  995.     Gadg_SetTag(&tags[2],TAG_MORE,(ULONG)opu->opu_AttrList);
  996.   return DoSuperMethod(cl,o,OM_NOTIFY,tags,opu->opu_GInfo,opu->opu_Flags);
  997. }
  998.